Skip to content

SLM-418: write replay-preference corpus + run real preference train (DSH5-10, seventh slice) - #1149

Closed
Tyler-R-Kendrick wants to merge 2 commits into
mainfrom
claude/great-dirac-uk9exi
Closed

SLM-418: write replay-preference corpus + run real preference train (DSH5-10, seventh slice)#1149
Tyler-R-Kendrick wants to merge 2 commits into
mainfrom
claude/great-dirac-uk9exi

Conversation

@Tyler-R-Kendrick

@Tyler-R-Kendrick Tyler-R-Kendrick commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Summary

Seventh slice of DSH5-10 (SLM-418). The sixth slice (v7) built and tested PreferencePair conversion for the seven named replay-preference relation patterns but never wrote a pair to a corpus file or fed it into the real training harness. This slice closes exactly that gap for the bounded synthetic corpus (synthesize_bounded_session_corpus):

  • Writes the corpus's train/held-out PreferencePair splits to real corpus files under the existing outputs/data/preference/ root (no shadow corpus tree).
  • Runs the real, unchanged slm preference train harness against a from-scratch wf_smoke_v2 TwoTowerModel checkpoint.
  • Adds pairwise_preference_margin / held_out_pairwise_accuracy / evaluate_replay_preference_held_out_benefit to train.py, reusing dpo_loss's own log-prob machinery rather than a parallel scoring path.
  • Honestly measures held-out pairwise-preference accuracy before/after training: 1.0 baseline, 1.0 trained on 4 held-out pairs — a ceiling effect, so the verdict is no_benefit_fixture_scale, not a benefit claim. claim_class: wiring throughout.

The DSH3-selected TypedOperatorPolicyScorer, the four-baseline comparison, and CAP0/CAP1/CAP2 retention remain explicitly out of scope (unchanged from every prior slice's own scope notes).

What changed

  • src/slm_training/harnesses/preference/replay_preference_corpus.py (new) — corpus conversion/writer.
  • scripts/build_replay_preference_corpus.py (new) — CLI to write train/held-out pairs.
  • scripts/measure_replay_preference_held_out_benefit.py (new) — CLI wrapping the held-out measurement.
  • src/slm_training/harnesses/preference/train.py — new margin/accuracy/benefit-evaluation functions.
  • src/slm_training/harnesses/preference/replay_preference_context_view_variants.py — additive trace field on ReplayPreferenceSessionV1.
  • src/slm_training/resources/versions.jsonharness.preference.replay_preference_context_view_variants v2→v3; new harness.preference.replay_preference_corpus v1.
  • tests/test_harnesses/preference/test_replay_preference_corpus.py (new, 8 tests), test_replay_preference_held_out_benefit.py (new, 7 tests), one added test in test_operator_history_pairs.py.
  • docs/design/dsh5-10-replay-preference-rows.md — new "Seventh slice" section per documenting-experiment-results.

Test plan

Independently re-verified in this session (not just the authoring agent's own report), with NODE_OPTIONS= cleared per this repo's documented Node 22 constraint:

  • pytest -q tests/test_harnesses/preference/test_replay_preference_corpus.py tests/test_harnesses/preference/test_replay_preference_held_out_benefit.py tests/test_harnesses/preference/test_operator_history_pairs.py → 31 passed
  • ruff check on every touched/created file → clean
  • python -m scripts.verify_version_stamps --check --base origin/main → ok (2 components touched)
  • python -m scripts.repo_policy → ok (tracked + untracked)
  • python -m scripts.verify_decode_invariants → exit 0

No ship or benefit claim is made; this is wiring evidence, consistent with every prior slice in docs/design/dsh5-10-replay-preference-rows.md.


Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added tools to build replay-preference training and held-out datasets.
    • Added held-out evaluation comparing baseline and trained model preference accuracy.
    • Added reporting for pairwise margins, accuracy, skipped records, and benefit verdicts.
    • Preserved trace-backed session data for reliable replay corpus generation.
  • Documentation

    • Updated reproducibility instructions, expected outputs, and seventh-slice status.
  • Tests

    • Added coverage for corpus generation, trace availability, held-out evaluation, and failure-closed empty-corpus handling.

…DSH5-10, seventh slice)

Closes the sixth slice's own gap: writes the bounded synthetic corpus's
train/held-out PreferencePair splits to real corpus files under this repo's
existing preference-pairs root, then runs the real, unchanged `slm
preference train` harness against a from-scratch wf_smoke_v2 checkpoint.
Held-out pairwise-preference accuracy is honestly measured before/after
training (train.py gains pairwise_preference_margin/held_out_pairwise_
accuracy/evaluate_replay_preference_held_out_benefit) -- real result is a
ceiling effect (1.0 baseline, 1.0 trained, on 4 held-out pairs), so verdict
is `no_benefit_fixture_scale`, not a benefit claim. The DSH3-selected
TypedOperatorPolicyScorer, four-baseline comparison, and CAP0/CAP1/CAP2
retention remain out of scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
slm-training Ready Ready Preview, Comment Jul 27, 2026 4:24pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Tyler-R-Kendrick, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1af5d007-9a3a-448f-a7fb-f4bd2bf15429

📥 Commits

Reviewing files that changed from the base of the PR and between ad9d2f5 and c4fd02a.

📒 Files selected for processing (3)
  • docs/design/dsh5-10-replay-preference-rows.md
  • src/slm_training/harnesses/preference/train.py
  • src/slm_training/resources/versions.json
📝 Walkthrough

Walkthrough

The seventh slice adds trace-backed replay preference corpus generation, train and held-out JSONL outputs, held-out checkpoint evaluation utilities, two CLI entry points, component registration, tests, and reproducibility documentation.

Changes

Replay preference pipeline

Layer / File(s) Summary
Trace-backed corpus generation
src/slm_training/harnesses/preference/replay_preference_context_view_variants.py, src/slm_training/harnesses/preference/replay_preference_corpus.py, tests/test_harnesses/preference/test_replay_preference_corpus.py, tests/test_harnesses/preference/test_operator_history_pairs.py
Sessions expose their originating traces except merge_success; replay rows convert through trace-based or direct conversion paths, and non-empty train/held-out corpora produce build reports and JSONL files.
Held-out checkpoint evaluation
src/slm_training/harnesses/preference/train.py, scripts/measure_replay_preference_held_out_benefit.py, tests/test_harnesses/preference/test_replay_preference_held_out_benefit.py
The harness computes pairwise margins, tie-aware accuracy, and baseline-versus-trained verdicts; the CLI loads held-out pairs, prints the report, and optionally writes it.
Slice documentation and reproducibility
scripts/build_replay_preference_corpus.py, src/slm_training/resources/versions.json, docs/design/dsh5-10-replay-preference-rows.md
The corpus-builder CLI supports train, held-out, or both splits, while registry metadata and design documentation describe the seventh-slice interfaces, commands, outputs, and scope.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CorpusCLI as build_replay_preference_corpus
  participant CorpusWriter as write_replay_preference_corpus
  participant Sessions as synthesize_bounded_session_corpus
  participant Converter as preference_pairs_from_trace
  participant JSONL as write_pairs
  CorpusCLI->>CorpusWriter: select corpus split
  CorpusWriter->>Sessions: synthesize sessions
  Sessions-->>CorpusWriter: trace-backed sessions
  CorpusWriter->>Converter: convert replay rows
  Converter-->>CorpusWriter: PreferencePair records
  CorpusWriter->>JSONL: persist JSONL corpus
Loading
sequenceDiagram
  participant BenefitCLI as measure_replay_preference_held_out_benefit
  participant Evaluator as evaluate_replay_preference_held_out_benefit
  participant Accuracy as held_out_pairwise_accuracy
  participant Model as TwoTowerModel
  BenefitCLI->>Evaluator: provide checkpoints and held-out pairs
  Evaluator->>Model: load checkpoint
  Evaluator->>Accuracy: compute pairwise accuracy
  Accuracy-->>Evaluator: accuracy and mean margin
  Evaluator-->>BenefitCLI: JSON benefit verdict
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: building the replay-preference corpus and running real preference training for the seventh DSH5-10 slice.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/great-dirac-uk9exi

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/design/dsh5-10-replay-preference-rows.md`:
- Around line 851-855: Update the checkpoint documentation section to require
and describe the corresponding docs/MODEL_CARD.md and README model-card
summaries for the checkpoints created by this slice, including their local
smoke-scale status; remove the statement that no model-card update applies.
- Around line 885-904: Prefix every newly added command example with the
mandatory rtk wrapper: update all commands in
docs/design/dsh5-10-replay-preference-rows.md lines 885-904, the training and
preference-training commands in lines 769-799, and both module usage examples in
scripts/build_replay_preference_corpus.py lines 5-6, including the
NODE_OPTIONS-assigned pytest invocation.

In `@scripts/build_replay_preference_corpus.py`:
- Around line 5-6: Update the usage commands in the module docstring for
build_replay_preference_corpus to prefix each invocation with rtk, preserving
the existing arguments and command behavior.
- Around line 50-54: Validate in the argument-handling flow before the `reports`
writes that `args.train_out` and `args.held_out_out` resolve to distinct paths
whenever `args.split` is `"both"`. Reject the invocation with a clear error and
non-success exit status before calling `write_replay_preference_corpus`, while
preserving existing behavior for single-split modes.

In `@src/slm_training/harnesses/preference/train.py`:
- Around line 210-273: Add a version_stamp to both result dictionaries returned
by evaluate_replay_preference_held_out_benefit, including the
no_trained_checkpoint early return and the final comparison return. Generate it
with
build_version_stamp("harness.preference.replay_preference_held_out_benefit"),
following ReplayPreferenceCorpusBuildReportV1, and update the component version
or add the required no-bump note in versions.json.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 405292d4-7d89-4b17-99fd-85addca7b17a

📥 Commits

Reviewing files that changed from the base of the PR and between 4d650b7 and ad9d2f5.

📒 Files selected for processing (10)
  • docs/design/dsh5-10-replay-preference-rows.md
  • scripts/build_replay_preference_corpus.py
  • scripts/measure_replay_preference_held_out_benefit.py
  • src/slm_training/harnesses/preference/replay_preference_context_view_variants.py
  • src/slm_training/harnesses/preference/replay_preference_corpus.py
  • src/slm_training/harnesses/preference/train.py
  • src/slm_training/resources/versions.json
  • tests/test_harnesses/preference/test_operator_history_pairs.py
  • tests/test_harnesses/preference/test_replay_preference_corpus.py
  • tests/test_harnesses/preference/test_replay_preference_held_out_benefit.py

Comment on lines +851 to +855
* Checkpoint promotion, syncing, or `docs/MODEL_CARD.md` / README updates --
both checkpoints this slice produces are local, from-scratch/smoke-scale,
and gitignored (`outputs/` is never committed); neither is a roster,
matrix-champion, or production-ship checkpoint, so no model-card update
applies.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Apply the required model-card updates for created checkpoints.

This slice creates checkpoints at Lines 775-777 and 793-794, but this section says no docs/MODEL_CARD.md or README update applies. That contradicts the repository rule requiring both model-card summaries whenever checkpoints are created, even when they are local smoke-scale artifacts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/design/dsh5-10-replay-preference-rows.md` around lines 851 - 855, Update
the checkpoint documentation section to require and describe the corresponding
docs/MODEL_CARD.md and README model-card summaries for the checkpoints created
by this slice, including their local smoke-scale status; remove the statement
that no model-card update applies.

Source: Coding guidelines

Comment on lines +885 to +904
```bash
NODE_OPTIONS= pytest -q tests/test_harnesses/preference/test_replay_preference_corpus.py tests/test_harnesses/preference/test_replay_preference_held_out_benefit.py tests/test_harnesses/preference/test_operator_history_pairs.py tests/test_dsl/test_replay_preference.py tests/test_evals/test_ambiguous_operator_followups.py
python -m scripts.build_replay_preference_corpus --split both
python -m scripts.train_model --train-dir src/slm_training/resources/data/train/wf_smoke_v2 \
--model twotower --context-backend scratch --steps 8 \
--run-id dsh5_10_seventh_slice_scratch --no-sync-checkpoints --device cpu --seed 0
python -m scripts.train_preference train \
--checkpoint outputs/runs/dsh5_10_seventh_slice_scratch/checkpoints/last.pt \
--pairs outputs/data/preference/replay_preference_train_pairs.jsonl \
--out-dir outputs/runs/dsh5_10_seventh_slice_preference --steps 20 --device cpu
python -m scripts.measure_replay_preference_held_out_benefit \
--baseline-checkpoint outputs/runs/dsh5_10_seventh_slice_scratch/checkpoints/last.pt \
--trained-checkpoint outputs/runs/dsh5_10_seventh_slice_preference/model.pt \
--held-out-pairs outputs/data/preference/replay_preference_held_out_pairs.jsonl \
--device cpu --seed 0
python -m scripts.verify_version_stamps --check --base origin/main
python -m scripts.repo_policy
python -m scripts.verify_decode_invariants
ruff check src/slm_training/harnesses/preference/replay_preference_context_view_variants.py src/slm_training/harnesses/preference/train.py src/slm_training/harnesses/preference/replay_preference_corpus.py scripts/build_replay_preference_corpus.py scripts/measure_replay_preference_held_out_benefit.py tests/test_harnesses/preference/test_replay_preference_corpus.py tests/test_harnesses/preference/test_replay_preference_held_out_benefit.py tests/test_harnesses/preference/test_operator_history_pairs.py
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the mandatory rtk wrapper in all newly added command examples.

The added shell commands bypass the repository-wide rtk requirement; update each affected example, including the environment-assigned pytest invocation.

  • docs/design/dsh5-10-replay-preference-rows.md#L885-L904: prefix the seventh-slice reproducibility commands with rtk.
  • docs/design/dsh5-10-replay-preference-rows.md#L769-L799: prefix the training and preference-training commands with rtk.
  • scripts/build_replay_preference_corpus.py#L5-L6: prefix both module usage examples with rtk.
📍 Affects 2 files
  • docs/design/dsh5-10-replay-preference-rows.md#L885-L904 (this comment)
  • docs/design/dsh5-10-replay-preference-rows.md#L769-L799
  • scripts/build_replay_preference_corpus.py#L5-L6
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/design/dsh5-10-replay-preference-rows.md` around lines 885 - 904, Prefix
every newly added command example with the mandatory rtk wrapper: update all
commands in docs/design/dsh5-10-replay-preference-rows.md lines 885-904, the
training and preference-training commands in lines 769-799, and both module
usage examples in scripts/build_replay_preference_corpus.py lines 5-6, including
the NODE_OPTIONS-assigned pytest invocation.

Source: Coding guidelines

Comment on lines +5 to +6
python -m scripts.build_replay_preference_corpus
python -m scripts.build_replay_preference_corpus --split train --out outputs/data/preference/replay_preference_train_pairs.jsonl

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Prefix the usage commands with rtk.

The module docstring adds raw shell commands instead of the repository-required rtk-prefixed form.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/build_replay_preference_corpus.py` around lines 5 - 6, Update the
usage commands in the module docstring for build_replay_preference_corpus to
prefix each invocation with rtk, preserving the existing arguments and command
behavior.

Source: Coding guidelines

Comment on lines +50 to +54
reports = []
if args.split in ("train", "both"):
reports.append(write_replay_preference_corpus(args.train_out, "train"))
if args.split in ("held_out", "both"):
reports.append(write_replay_preference_corpus(args.held_out_out, "held_out"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Reject identical output paths for --split both.

If --train-out and --held-out-out resolve to the same path, the held-out write overwrites the train corpus while stdout still reports two successful builds.

Proposed validation
     args = parser.parse_args(argv)

+    if (
+        args.split == "both"
+        and args.train_out.resolve() == args.held_out_out.resolve()
+    ):
+        parser.error("--train-out and --held-out-out must be different")
+
     reports = []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
reports = []
if args.split in ("train", "both"):
reports.append(write_replay_preference_corpus(args.train_out, "train"))
if args.split in ("held_out", "both"):
reports.append(write_replay_preference_corpus(args.held_out_out, "held_out"))
args = parser.parse_args(argv)
if (
args.split == "both"
and args.train_out.resolve() == args.held_out_out.resolve()
):
parser.error("--train-out and --held-out-out must be different")
reports = []
if args.split in ("train", "both"):
reports.append(write_replay_preference_corpus(args.train_out, "train"))
if args.split in ("held_out", "both"):
reports.append(write_replay_preference_corpus(args.held_out_out, "held_out"))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/build_replay_preference_corpus.py` around lines 50 - 54, Validate in
the argument-handling flow before the `reports` writes that `args.train_out` and
`args.held_out_out` resolve to distinct paths whenever `args.split` is `"both"`.
Reject the invocation with a clear error and non-success exit status before
calling `write_replay_preference_corpus`, while preserving existing behavior for
single-split modes.

Comment thread src/slm_training/harnesses/preference/train.py
…report

evaluate_replay_preference_held_out_benefit's two returned dicts now carry
version_stamp (build_version_stamp("harness.preference.replay_preference_corpus")),
matching the sibling ReplayPreferenceCorpusBuildReportV1 report and this
repo's "results carry version_stamp" law -- was previously missing it.

A second CodeRabbit finding (build_replay_preference_corpus.py should reject
--split both when --train-out/--held-out-out collide) is real and correct
but not landed here: this repo's changed-tests pre-commit hook maps any
scripts/-prefixed change to the full tests/test_scripts suite, which has
pre-existing failures unrelated to this slice (confirmed by stashing this
fix and reproducing the same failures against unmodified HEAD). Documented
in docs/design/dsh5-10-replay-preference-rows.md's "Review fixes (seventh
slice)" for a future session to land once that suite's pre-existing
breakage is fixed. The three remaining CodeRabbit comments (rtk-prefix x3,
model-card update) are not applied, with reasons, in the same doc section.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@Tyler-R-Kendrick Tyler-R-Kendrick left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review — went through all 5 comments against the current code rather than applying blind:

  • Missing version_stamp on the held-out benefit report (Major) — real, fixed in c4fd02a. Both returned dicts now stamp with build_version_stamp("harness.preference.replay_preference_corpus"), matching the sibling report.
  • --split both same-path collision (Minor) — real and the proposed fix is correct, but not landed this round: this repo's .githooks/check-changed pre-commit hook maps any scripts/-prefixed change to the full tests/test_scripts suite, which currently has pre-existing failures unrelated to this PR (confirmed by stashing the fix and reproducing the same failures against unmodified HEAD). Deferring to a follow-up once that suite's pre-existing breakage is fixed, rather than forcing the commit through with --no-verify. Documented in docs/design/dsh5-10-replay-preference-rows.md's "Review fixes (seventh slice)".
  • rtk-prefix on command examples (3 comments) — not applied. Same suggestion this exact doc already reviewed and rejected in "Review fixes (sixth slice)": rtk is a token-compression convenience for an agent's own shell usage, not part of the documented, copy-pasteable reproduction commands.
  • Model-card update required (Major) — not applied. docs/MODEL_CARD.md's own stated scope is checkpoints "intended for reuse"; this slice's two checkpoints are local, from-scratch smoke checkpoints, gitignored and never synced/promoted, consistent with every prior smoke-loop iteration in this repo.

Full reasoning for each is in the doc's new "Review fixes (seventh slice)" section.


Generated by Claude Code

@Tyler-R-Kendrick Tyler-R-Kendrick left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking merge: this PR contradicts the final SLM-418 disposition (PR #1157, merged f5259ea1), published on 2026-07-27 after this slice's work began.

The disposition (docs/design/iter-slm418-dsh5-10-disposition-20260727.md) is an explicit falsification close with decision no_held_out_benefit_at_fixture_scale_retain_dag_only, invoking the issue's own stop rule verbatim: 'If replay-grounded history yields no held-out benefit, retain the event DAG for runtime/evaluation only and do not add preference training complexity.' Its non-goals state: 'No preference training complexity added — no SFT/preference training run, no checkpoint'.

This PR does exactly what the disposition forecloses:

  1. It runs a real slm preference train run (20 steps) against the replay-preference train split and writes a trained checkpoint.
  2. It does so against the same bounded synthetic fixture corpus (8 sessions, 36 train / 4 held-out pairs via synthesize_bounded_session_corpus) that already produced the no_benefit_fixture_scale ceiling effect — its own measured verdict is again no_benefit_fixture_scale (1.0 baseline vs 1.0 trained on the 4-pair held-out split), confirming rather than rebutting the falsification.
  3. It adds preference-training measurement machinery (pairwise_preference_margin, held_out_pairwise_accuracy, evaluate_replay_preference_held_out_benefit in train.py plus two CLIs) whose sole purpose is to justify preference training — training complexity the disposition says not to add.

The disposition's own successor conditions (goal-drift guard I14) define what would re-open preference training: (1) a real, argument-bound corpus build — the VAR3-04/05 pattern, pointing the extraction/conversion pipeline at build_symbolic_operator_corpus real admitted documents — measured against current_state_only/derived-only baselines, and (2) a powered held-out split that the state-only feature cannot ceiling. Neither is met: this slice's corpus is the synthetic fixture, and its held-out split is the same 4 pairs.

The honest fix is not to land a seventh synthetic slice but, if the goal is still pursued, to satisfy successor condition (1) first: build the real argument-bound corpus and beat derived-only baselines on a powered split, then file the preference-training successor per I14. A PR that retrains on the same fixture that falsified the approach adds complexity without evidence and sets a precedent of working around falsification closes by relabeling them 'in progress'.

The code itself looks careful (fail-closed empty-split guard, honest version_stamps, fixture-scale labeling), but sound engineering of a disposition-contradicting direction is still the wrong direction. Do not merge in this form.

@Tyler-R-Kendrick Tyler-R-Kendrick left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, closing this rather than trying to salvage it.

Verified independently: f5259ea (PR #1157) is a real, merged falsification-close disposition for this exact issue, and its non-goals explicitly say "no SFT/preference training complexity added." This PR's own measured result (no_benefit_fixture_scale, 1.0 baseline vs 1.0 trained on the same 8-session/40-row synthetic fixture) doesn't rebut that disposition — it's the same ceiling effect on the same fixture, just re-run with an actual training step added on top.

What happened: this PR's work was scoped from an earlier read of the repo state, before #1157 landed and merged — a genuine timing collision, not a disagreement with the disposition's reasoning. It should have re-checked for a closing disposition before adding preference-training machinery, and didn't.

Not attempting to rescue this into something that satisfies successor condition I14 (real argument-bound corpus via build_symbolic_operator_corpus, measured against derived-only baselines on a powered split) — that's a substantially different, larger PR, not a patch on this one. Closing as-is; if that work happens, it should be filed as its own successor per the disposition, starting from the corpus-build step, not from this branch.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants